package yxy.game.pm2.active.handle;

import org.joda.time.DateTime;
import org.joda.time.Period;
import yxy.apple.util.RandomUtility;
import yxy.apple.util.concurrent.ThreadPoolManager;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.actexchangeproduce;
import yxy.cherry.data.bean.vipdata;
import yxy.cherry.data.script.fomula;
import yxy.game.pm2.Result;
import yxy.game.pm2.active.module.ActiveModule_冲榜;
import yxy.game.pm2.active.module.actdata.ActDataCenter;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.currency.CurrencyNotEnoughException;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.module.RedisLock;
import yxy.game.pm2.bean.module.rank.active.RankRushEnum;
import yxy.game.pm2.bean.module.rank.active.RankRushHandle;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.task.TaskType;
import yxy.game.pm2.message.ActiveMessage;
import yxy.game.pm2.message.PackageMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.conquest.ConquestHandle;
import yxy.game.pm2.module.conquest.ConquestModule;
import yxy.game.pm2.module.task.TaskHandle;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

/** 限时兑换 征战 */
public class Act_ConquestHandle extends ConquestHandle {

	/**
	 * 限时兑换 挂机奖励
	 * 
	 * @param playerCode
	 * @param response
	 * @return
	 */
	public Result idleBonus_Act限时兑换(String playerCode, ActiveMessage.ActLimitExchangeConquestIdleBonusResponse.Builder response) {
		int mintime = fomula.挂机时长最小时间.intValue();
		long maxTimeMillis = get挂机最大时长(playerCode);
		long minTimeMillis = Period.seconds(mintime).toStandardDuration().getMillis();
		ConquestModule conquestModule = ConquestModule.get(playerCode);
		try {
			if (conquestModule.tryLock()) {
				int mapId = conquestModule.getMapId();
				DateTime startTime = conquestModule.timeline().getStartTime();
				DateTime now = DateTime.now();

				long time = now.getMillis() - startTime.getMillis();
				if (time < minTimeMillis) {
					return Result.ConquestIdleTimeTooClosed;// 领取挂机奖励时间太短了
				}
				if (time > maxTimeMillis) {
					time = maxTimeMillis;
				}
				Collection<Currency> rewards = vipReward(playerCode, holdReward(mapId, time));
				Collection<Currency> rndRewards = vipReward(playerCode, sweepReward(mapId, time));

				// 计算限时兑换活动随机奖励
				Collection<Currency> xianshiduihuan = sweepReward_Act限时兑换(mapId, time, playerCode);
				ArrayList<Currency> rndcurs = new ArrayList<Currency>(rndRewards);
				rndcurs.addAll(xianshiduihuan);

				// 结算奖励
				new CurrencyHandle().addCurrency(playerCode, CCReason.征战, rewards);
				new CurrencyHandle().addCurrency(playerCode, CCReason.征战, rndcurs);

				conquestModule.timeline().setStartTime(now);
				conquestModule.set();

				PlayerBean player = PlayerBean.get(playerCode);

				response.setTime(time);
				response.setLevel(player.getLevel());
				response.setExp(Currency.number(playerCode, CurrencyType.CT_主公经验, 0,false));
				response.addAllRewards(new CurrencyHandle().packPoints(rewards));
				response.addAllRndRewards(new CurrencyHandle().packItems(rndcurs));

				return Result.Success;
			}
		} catch (Exception e) {
		} finally {
			conquestModule.unlock();
		}

		return Result.DataError;
	}

	/**
	 * 限时兑换 扫荡
	 * 
	 * @param playerCode
	 * @param response
	 * @return
	 */
	public Result sweepOnce_Act限时兑换(String playerCode, ActiveMessage.ActLimitExchangeConquestSweepOnceResponse.Builder response) {
		RedisLock lock = ConquestModule.lock(playerCode);
		try {
			if (lock.tryLock()) {
				ConquestModule conquestModule = ConquestModule.get(playerCode);
				int remain = conquestModule.remainsweeptimes();
				if (remain <= 0) {
					return Result.ConquestSweepNoTimes;// 扫荡没有次数了
				}
				int times = conquestModule.sweeptimes();
				int costNum = fomula.征战快速作战花费元宝.intValue(times);
				Currency cost = Currency.create(CurrencyType.CT_元宝, 0, costNum);
				try {
					new CurrencyHandle().cost(playerCode, CCReason.征战, cost);
				} catch (CurrencyNotEnoughException e) {
					new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
				}

				int mapId = conquestModule.getMapId();
				long time = Period.seconds(fomula.征战快速作战收益时间.intValue()).toStandardDuration().getMillis();

				Collection<Currency> rewards = vipReward(playerCode, holdReward(mapId, time));
				Collection<Currency> rndRewards = vipReward(playerCode, sweepReward(mapId, time));

				Collection<PackageMessage.Currency> allRewards = new CurrencyHandle().packPoints(rewards);

				// 计算限时兑换活动随机奖励
				Collection<Currency> xianshiduihuan = sweepReward_Act限时兑换(mapId, time, playerCode);
				rndRewards.addAll(xianshiduihuan);

				Collection<PackageMessage.Item> allRndRewards = new CurrencyHandle().packItems(rndRewards);

				rewards.addAll(rndRewards);
				//改为异步推送
				Runnable runnable = () -> {
					// 结算奖励
					new CurrencyHandle().addCurrency(playerCode, CCReason.征战, rewards);
					TaskHandle.handle(playerCode, TaskType.统计型_征战_扫荡_次数, 1);
					//todo 每次循环的前半小时内不开启榜
					ActiveModule_冲榜 am = ActiveModule_冲榜.get(playerCode, false);
					DateTime begin = am.getRunend().minusDays(6).withHourOfDay(0).withMinuteOfHour(30).withSecondOfMinute(0).withMillisOfSecond(0);
					if (!DateTime.now().isBefore(begin)) {
						RankRushHandle.addRankRushData(playerCode, 1, RankRushEnum.冲榜_快速作战.getType());
					}
				};
				ThreadPoolManager.getInstance().execute(runnable);
				if (costNum <= 0) {
					conquestModule.setSweepFreeTimes(conquestModule.getSweepFreeTimes() + 1);
				}
				conquestModule.setSweepTimes(conquestModule.getSweepTimes() + 1);
				conquestModule.setLastSweepTime(DateTime.now());
				conquestModule.set();

				remain = conquestModule.remainsweeptimes();
				times = conquestModule.sweeptimes();
				boolean privilege = conquestModule.isPrivilege();

				PlayerBean player = PlayerBean.get(playerCode);

				response.setTime(time);
				response.setLevel(player.getLevel());
				response.setExp(Currency.number(playerCode, CurrencyType.CT_主公经验, 0,false));
				response.addAllRewards(allRewards);
				response.addAllRndRewards(allRndRewards);
				response.setTimes(times);
				response.setReleaseTimes(remain);
				response.setPrivilege(privilege);

				return Result.Success;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}

		return Result.DataError;
	}

	/** vip特权收益 */
	private Collection<Currency> vipReward(String playerCode, Collection<Currency> rewards) {
		PlayerBean playerBean = PlayerBean.get(playerCode);
		int viplevel = playerBean.getViplevel();
		vipdata _vipdata = DataCenter.getData(viplevel, vipdata.class);
		if (_vipdata == null) {
			return rewards;
		}
		for (Currency reward : rewards) {
			switch (reward.getType()) {
			case CT_主公经验:
				reward.setNumber(reward.getNumber() + reward.getNumber() * _vipdata.getVar1() / 10000);
				break;
			case CT_钱币:
				reward.setNumber(reward.getNumber() + reward.getNumber() * _vipdata.getVar2() / 10000);
				break;
			case CT_武将经验:
				reward.setNumber(reward.getNumber() + reward.getNumber() * _vipdata.getVar3() / 10000);
				break;
			default:
			}
		}
		return rewards;
	}

	/**
	 * 扫荡挂机随机奖励
	 * 
	 * @param time 挂机时间（毫秒）
	 */
	static public Collection<Currency> sweepReward_Act限时兑换(int mapId, long time, String playercode) {
		ArrayList<Currency> rewards = new ArrayList<>();

		Map<String, actexchangeproduce> map = ActDataCenter.getAllData(actexchangeproduce.class, playercode);
		actexchangeproduce data = null;

		Collection<actexchangeproduce> datas = map.values();
		for (actexchangeproduce execl : datas) {
			int levelmin = execl.getLevelmin();
			int levelmax = execl.getLevelmax();

			if (mapId >= levelmin && mapId <= levelmax) {
				data = execl;
			}
		}

		if (data == null) {
			return rewards;
		}

		int minute = data.getMininterval(); // 结算分钟数
		long millis = Period.minutes(minute).toStandardDuration().getMillis();
		if (millis <= 0 || millis > time) {
			return rewards;
		}
		long times = time / millis;

		int type = data.getRewardtype(); // 奖励类型
		int id = data.getRewardid();// 奖励id
		int min = data.getRewardnummin();// 最小数量
		int max = data.getRewardnummax();// 最大数量
		int prob = data.getProbability();// 奖励概率 万分比

		long num = 0;
		for (int t = 0; t < times; t++) {
			if (RandomUtility.ppm() > prob * 100) {
				continue;
			}
			num += RandomUtility.nextInt(min, max + 1);
		}
		rewards.add(Currency.create(type, id, num));

		return Currency.merge(rewards);
	}

}
